import { EBundleType } from "../Common/Enum";
import { LoadUtil } from "./LoadUtil";

const { ccclass, property } = cc._decorator;

export enum EMusicType {
    Null = '',
    StoryBgm = 'storyBgm',
    HomeBgm = 'homeBgm',
    TownBgm = 'townBgm',
    MusicHospital = 'MusicHospital',
    SyringeBgm = '扎针BGM',
}

export enum ESoundType {
    Click = "clickButton",
    RewardView = 'rewardView',
    ResGold = 'resGold',

    // Hospital
    HospitalUp = 'hospitalUp',
    HospitalDoor = 'hospitalDoor',
    HospitalItem = 'hospitalItem',
    HospitalClearup = 'hospitalClearup',
    HospitalGuestComplete = 'hospitalGuestComplete',
    HospitalSuccess = 'hospitalSuccess',
    HospitalFail = 'hospitalFail',
}

@ccclass
export default class AudioManager {
    private static _instance: AudioManager;
    public static get instance(): AudioManager {
        if (!this._instance) {
            this._instance = new AudioManager();
        }
        return this._instance;
    }

    public audioDatas: Map<EMusicType | ESoundType | string, cc.Asset> = new Map();

    /** 记录当前的背景音乐 */
    private musicType: EMusicType = EMusicType.Null;

    /** 播放音效? */
    private enabled: boolean = true;

    public isLoadComplete: boolean = false;

    public initAudioInfos() {
        LoadUtil.instance.loadDir(EBundleType.PUBLIC, () => {
            this.isLoadComplete = true;
        });
    }

    public playMusic(type: EMusicType, volume: number = 1) {
        if (!this.enabled) return;
        if (this.musicType === type) return;
        this.musicType = type;
        const audioClip = this.audioDatas.get(type) as cc.AudioClip;
        cc.audioEngine.playMusic(audioClip, true);
        cc.audioEngine.setMusicVolume(volume);
    }

    public playSound(type: ESoundType | string, volume: number = 1) {
        if (!this.enabled) return;
        const audioClip = this.audioDatas.get(type) as cc.AudioClip;
        cc.audioEngine.playEffect(audioClip, false);
        cc.audioEngine.setEffectsVolume(volume);
    }

    public stopMusic() {
        this.musicType = null;
        cc.audioEngine.stopMusic();
    }

    public setEnabled(enabled: boolean) {
        this.enabled = enabled;
        if (this.enabled) {
            this.playMusic(this.musicType);
        } else {
            cc.audioEngine.stopAll();
        }
    }

    public pauseMusic() {
        cc.audioEngine.pauseMusic();
    };

    public resumeMusic() {
        cc.audioEngine.resumeMusic();
    };

    public getEnable() {
        return this.enabled;
    }
}






// /**
//  * 音频播放信息
//  *
//  * @private
//  * @type {Map<string, {ts: number}>}
//  * @memberof GameUtil
//  */
// private playAudioInfos: Map<string, { ts: number }> = new Map();

// /**
//  * 背景音乐数组
//  *
//  * @private
//  * @type {number[]}
//  * @memberof GameUtil
//  */
// private playMusicAudioIds: number[] = [];

// /**
//  * 背景音乐音量
//  *
//  * @private
//  * @type {number[]}
//  * @memberof GameUtil
//  */
// private musicVolumes: number[] = [];

// /**
//  * 最终的音乐音量
//  *
//  * @private
//  * @type {number}
//  * @memberof GameUtil
//  */
// private finalMusicVolume: number = 1;

// private playEffectVoiceRefNum: number = 0;
// /**
//  * 播放背景音乐
//  *
//  * @param {string} url
//  * @param {boolean} [loop=true]
//  * @param {number} [volume=1.0]
//  * @returns
//  */
// public playMusic(url: string, loop: boolean = true) {
//     // 停止当前正在播放的背景音乐
//     if (this.playMusicAudioIds.length > 0) {
//         const originAudioId = this.playMusicAudioIds[this.playMusicAudioIds.length - 1];
//         cc.audioEngine.pause(originAudioId);
//     }
//     // 播放新的背景音乐
//     const audioClip = cc.loader.getRes(url, cc.AudioClip);
//     if (_.isNil(audioClip)) {
//         CC_PREVIEW && console.warn("GameUtil: audioClip is nil", url);
//         return;
//     }
//     const audioId = this.playAudio(audioClip, loop, this.finalMusicVolume, url);
//     if (audioId === -1) {
//         CC_PREVIEW && console.warn("GameUtil: audioId is -1", url);
//         return;
//     }
//     // 加入已播放背景音乐数组
//     this.playMusicAudioIds.push(audioId);
//     return audioId;
// }

// /**
//  * 停止当前的背景音乐，如果之前有正在播放的背景音乐，恢复
//  *
//  * @returns
//  * @memberof GameUtil
//  */
// public stopMusic(duration: number = 0) {
//     if (this.playMusicAudioIds.length <= 0) {
//         return;
//     }
//     const currentAudioId = this.playMusicAudioIds.pop();
//     this.stopAudio(currentAudioId, duration);
//     if (this.playMusicAudioIds.length <= 0) {
//         return;
//     }
//     const audioId = this.playMusicAudioIds[this.playMusicAudioIds.length - 1];
//     cc.audioEngine.resume(audioId);
//     cc.audioEngine.setCurrentTime(audioId, 0);
//     this.updateMusic();
// }

// /**
//  * 背景音乐控制 增加
//  *
//  * @param {number} volume
//  * @param {number} [duration=0]
//  * @memberof GameUtil
//  */
// public addMusicVolumeRule(volume: number) {
//     this.musicVolumes.push(volume);
//     this.updateMusic();
// }

// /**
//  * 背景音乐控制 删除
//  *
//  * @param {number} volume
//  * @memberof GameUtil
//  */
// public delMusicVolumeRule(volume: number) {
//     this.musicVolumes.splice(this.musicVolumes.indexOf(volume), 1);
//     this.updateMusic();
// }

// /**
//  * 清空背景音乐控制规则
//  *
//  * @memberof GameUtil
//  */
// public clearVolumeRules() {
//     this.musicVolumes = [];
//     const musicOn = StorageUtil.instance.read(EStorageKey.BG_MUSIC, true, true);
//     !musicOn && this.addMusicVolumeRule(0);
// }

// /**
//  * 更新背景音乐
//  *
//  * @private
//  * @memberof GameUtil
//  */
// private updateMusic() {
//     this.finalMusicVolume = 1;
//     if (this.musicVolumes.length > 0) {
//         this.finalMusicVolume = _.min(this.musicVolumes);
//     }
//     const audioId = this.playMusicAudioIds[this.playMusicAudioIds.length - 1];
//     cc.audioEngine.setVolume(audioId, this.finalMusicVolume);
// }

// /**
//  * 播放音频
//  *
//  * @param {(string | cc.AudioClip)} url
//  * @param {boolean} [loop=false]
//  * @param {number} [volume=1.0]
//  * @returns {number}
//  * @memberof GameUtil
//  */
// public playEffect(url: string | cc.AudioClip, loop: boolean = false, volume: number = 1.0): number {
//     if (this.playEffectVoiceRefNum > 0) {
//         return;
//     }
//     const effectOn = StorageUtil.instance.read(EStorageKey.EFFECT_MUSIC, true, true);
//     if (!effectOn) {
//         return;
//     }
//     if (_.isNil(url)) {
//         console.warn("GameUtil: url is nil");
//         return;
//     }
//     let audioClip: cc.AudioClip = null;
//     if (typeof url === "string") {
//         audioClip = cc.loader.getRes(url, cc.AudioClip);
//     } else {
//         audioClip = url;
//         url = audioClip.nativeUrl;
//     }
//     if (_.isNil(audioClip)) {
//         console.warn("GameUtil: audioClip is nil");
//         return;
//     }
//     return this.playAudio(audioClip, loop, volume, url);
// }

// public playVoice(url: string, loop: boolean = false, volume: number = 1.0): number {
//     if (this.playEffectVoiceRefNum > 0) {
//         return;
//     }
//     const voiceOn = StorageUtil.instance.read(EStorageKey.VOICE_MUSIC, true, true);
//     if (!voiceOn) {
//         return;
//     }
//     const audioClip = cc.loader.getRes(url, cc.AudioClip);
//     if (_.isNil(audioClip)) {
//         console.warn("GameUtil: audioClip is nil");
//         return;
//     }
//     return this.playAudio(audioClip, loop, volume, url);
// }

// private playAudio(audioClip: cc.AudioClip, loop: boolean, volume: number, url: string): number {
//     let playAudioInfo = this.playAudioInfos.get(audioClip.nativeUrl);
//     if (_.isNil(playAudioInfo)) {
//         playAudioInfo = { ts: 0 };
//         this.playAudioInfos.set(audioClip.nativeUrl, playAudioInfo);
//     }
//     const interval = Date.now() - playAudioInfo.ts;
//     if (interval > 0 && interval <= 100) {
//         // 一定时间内，不允许重复播放同一个音效
//         // console.warn("GameUtil: audio play too frequently: ", url);
//         return;
//     }
//     const audioId = cc.audioEngine.play(audioClip, loop, volume);
//     if (audioId === -1) {
//         console.warn("GameUtil: audioId is -1", url);
//         return;
//     }
//     playAudioInfo.ts = Date.now();
//     return audioId;
// }

// /**
//  * 停止播放
//  *
//  * @param {number} audioId
//  * @param {boolean} [rightNow]
//  * @memberof GameUtil
//  */
// public stopAudio(audioId: number, durationMs: number = 0): void {
//     if (_.isNil(audioId)) {
//         return;
//     }
//     if (durationMs <= 0) {
//         cc.audioEngine.stop(audioId);
//         return;
//     }
//     let volume = cc.audioEngine.getVolume(audioId);
//     const stepTime = 100;
//     const stepVolume = volume / (durationMs / stepTime);
//     let handle = null;
//     const fn = () => {
//         volume -= stepVolume;
//         if (volume <= 0) {
//             cc.audioEngine.stop(audioId);
//             clearInterval(handle);
//         } else {
//             cc.audioEngine.setVolume(audioId, volume);
//         }
//     };
//     handle = setInterval(fn, stepTime);
// }

// public getAudioDuration(audioId: number) {
//     return cc.audioEngine.getDuration(audioId);
// }